#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>

/*
 * We cannot do the NULL trick at the end because we are not passing pointers. 0 would be interpreted as NULL
 * and the argument list would end prematurely.
 */
int count(int parity, int args, ...)
{
    va_list list;
    va_start(list, args);
    int result = 0;
    for(int i = 0; i < args; ++i)
    {
        if(parity)
            result += (va_arg(list, int)) % 2;
        else
            result += (va_arg(list, int) + 1) % 2;
    }
    va_end(list);
    return result;
}

/*
 * But we CAN use it here
 */
const char *concat_with_sep_impl(const char *sep, ...)
{
    size_t sep_len = strlen(sep);
    size_t arg_count = 0;
    size_t length = 0;

    va_list args;
    va_start(args, sep);
    for(char *arg = va_arg(args, char *); arg != NULL; arg = va_arg(args, char *))
    {
        arg_count += 1;
        length += strlen(arg);
    }

    va_end(args);

    if(!arg_count)
        return NULL;

    size_t n_seps = arg_count - 1;
    //                   parts     separators       \0
    char *result = malloc(length + n_seps * sep_len + 1);

    va_start(args, sep);
    length = 0;
    for(char *arg = va_arg(args, char *); arg != NULL; arg = va_arg(args, char*), n_seps--)
    {
        size_t n = strlen(arg);
        memcpy(result + length, arg, n);
        if(n_seps > 0)
            memcpy(result + length + n, sep, sep_len);
        length += n + sep_len;
    }
    *(result + length) = '\0';
    va_end(args);



    return result;
}

#define CONCAT_WITH_SEP(sep, ...) concat_with_sep_impl(sep, __VA_ARGS__, NULL)

int main(void){
    printf("10 and 14 are %d even numbers and %d odd numbers\n", count(0, 2, 10, 14), count(1, 2, 10, 14));
    printf("21 and 14 are %d even numbers and %d odd numbers\n", count(0, 2, 21, 14), count(1, 2, 21, 14));
    printf("21, 16, 23432, 35, 56 and 14 are %d even numbers and %d odd numbers\n", count(0, 5, 21, 16, 23432, 35, 56, 14), count(1, 5, 21, 16, 23432, 35, 56, 14));
    putchar('\n');
    printf("%s\n", CONCAT_WITH_SEP("\\\\", "home", "amf", "Programs", "Scheme"));
    return 0;
}
